/**
 * Copyright (C) 2002-2007 WUZEWEN. All rights reserved.
 * WUZEWEN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 * This software is the confidential and proprietary information of
 * WuZeven, Personal. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with WuZeven.
 */

package com.kingcore.pda.model.controller;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

import com.kingcore.pda.base.controller.PdaAction;


/**
 * <p>pda 系统模型功能处理Action。</p>
 * @author	WUZEWEN on 2005-12-1
 * @version	1.0
 * @see		Object#equals(java.lang.Object)
 * @see		Object#hashCode()
 * @see		HashMap
 * @since	JDK5
 */

public class ModelDealAction extends PdaAction {
	
	/**
	 * 日志处理对象
	 */
	Logger log = Logger.getLogger( this.getClass() );
	
	/**
	 * java xml 处理对象
	 */
	private DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

	private DocumentBuilder db = null;

	private Document doc = null;

	/**
	 * pda系统生成的项目的表文件、模型文件的存放位置。
	 */
	private String prj_path="E:/ProgramXP/pda/";

	/**
	 * 覆盖并实现基类的方法。
	 */
	public ActionForward executeAction(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 获取处理页面的哪个行为的参数
		String action = request.getParameter( "Action" );
		
		prj_path = request.getParameter( "prj_path" );
		if( request.getParameter( "prj_path" )!=null){
			prj_path = request.getParameter( "prj_path" );
		}

		//System.out.println("action="+action);

		// Action = 通过ajax获取模型文件内容信息
		if( action!=null && action.equals("getFileInfo")){
			return getModelFileInfo( mapping, form,
					request, response);

		// Action = 通过接收ajax请求创建新的模型文件
		}else if( action!=null && action.equals("create")){
			return createModelFileInfo( mapping, form,
					request, response);

		// Action = 删除模型文件
		}else if( action!=null && action.equals("deleteFile")){	//删除模型文件
			return deleteModelFile( mapping, form,
					request, response);
		}

		return null;
	}


	/**
	 * <p>要求线程安全。删除服务器端的模型文件。</p>
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 */
	private synchronized ActionForward deleteModelFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
		
		String fileName=request.getParameter("fileName");

		// 根据文件名称删除文件，并且输出信息给客户端。  -- 采用UTF-8格式
		PrintWriter printWriter = null;
		response.setContentType("text/xml;charset=UTF-8");
		try {
			printWriter = response.getWriter();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		printWriter.println("<response>");

		try{
			///fileName = StringUtils.toGB2312(fileName);
			log.info("delete file，file name is " + prj_path+"model/"+fileName+".woo.model.xml" );
			
			File file=new File(prj_path+"model/"+fileName+".woo.model.xml");
			if(file.exists()){
				file.delete();
				printWriter.println("<content>success</content>");
				printWriter.println("<content>文件删除成功！</content>");
			}else{
				printWriter.println("<content>fail</content>");
				printWriter.println("<content>文件不存在，删除失败！</content>");
				
			}
			
		}catch(Exception e){
			e.printStackTrace();
			printWriter.println("<content>fail</content>");
			printWriter.println("<content>文件删除失败："+e.getMessage()+"</content>");
		}

		printWriter.println("</response>");
		
		return null;
	}


	/**
	 * <p>要求线程安全
	 * 	  创建模型文件，开始采用获取请求信息，使用java xml类生成xml文件，
	 * 		后来采用直接写入String到xml文件的方式。</p>
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 */
	private synchronized ActionForward createModelFileInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {

		PrintWriter printWriter= null;
		try{

			//得到XML文档解析器和文档对象
			dbf.setNamespaceAware(true);
			db=dbf.newDocumentBuilder();
			doc=db.newDocument();
			String[] names=null;
			String[] types=null;
			String[] nullables=null;
			String[] notes=null;
			String[] checks=null;
			String[] shows=null;
			String modelName = request.getParameter("modelEn");//模型的英文名，即保存的文件名
			String modelNameNote = request.getParameter("modelCh");//模型的中文注释名
			String isConver = request.getParameter("isCover");
			if(modelName!=null && modelName.equals("")){
				modelName="Zeven";
				modelNameNote="modelNameNote";
			}
			

			
			///modelName = StringUtils.toGB2312(modelName);
			if(modelNameNote==null || modelNameNote.trim().equals("")){
				modelNameNote="XX模型";
			}else{
				modelNameNote = modelNameNote.trim();
				//modelNameNote = StringUtils.toGB2312(modelNameNote);
			}
			File file=new File(prj_path+"model/"+modelName+"___"+modelNameNote+".woo.model.xml");
			log.info( "创建模型文件："+file.getName() );
			
			
			if(file.exists() && isConver==null){
				// 提示文件已经存在，使用UTF-8格式。
				response.setContentType("text/xml;charset=UTF-8");
				printWriter = response.getWriter();
				printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
				printWriter.println("<response>");
				printWriter.println("<content>fileExists</content>");
				printWriter.println("</response>");
				return null;
			}
			
			if(false) {   // 这个是获取信息有Java xml 创建Dom的做法，取消了。
				//request.setCharacterEncoding("UTF8");
				if(request.getParameter("names")!=null 
					&& request.getParameter("types")!=null
					&& request.getParameter("notes")!=null 
					&& request.getParameter("checks")!=null 
					&& request.getParameter("shows")!=null ){
	
	
					//System.out.println( StringUtils.toGB2312(request.getParameter("notes")) );
	//				names = StringUtils.toGB2312( request.getParameter("names") ).split("@");
	//				types = StringUtils.toGB2312( request.getParameter("types") ).split("@");
	//				nullables = StringUtils.toGB2312( request.getParameter("nullables") ).split("@");
	//				notes = StringUtils.toGB2312( request.getParameter("notes") ).split("@");
	//				checks = StringUtils.toGB2312( request.getParameter("checks") ).split("@");
	//				shows = StringUtils.toGB2312( request.getParameter("shows") ).split("@");
					
					names = request.getParameter("names").split("@");
					types = request.getParameter("types").split("@");
					nullables = request.getParameter("nullables").split("@");
					notes = request.getParameter("notes").split("@");
					checks = request.getParameter("checks").split("@");
					shows = request.getParameter("shows").split("@");
						
	//				System.out.println( request.getParameter("names") );
	//				System.out.println( request.getParameter("types") );
	//				System.out.println( request.getParameter("notes") );
	//				System.out.println( request.getParameter("nullables") );
	
					//names = new String( request.getParameter("names").getBytes("ISO-8859-1"),"UTF-8" ).split("@");
					//types = new String( request.getParameter("types").getBytes("ISO-8859-1"),"UTF-8" ).split("@");
					//notes = new String( request.getParameter("notes").getBytes("ISO-8859-1"),"UTF-8" ).split("@");
	
	//				names = request.getParameter("names").split("@");
	//				types = request.getParameter("types").split("@");
	//				notes = request.getParameter("notes").split("@");
	
				}else{
					names= new String[]{"sss"};
					notes= new String[]{"sss"};
					types= new String[]{"sss"};
				}
				Element model =this.createElement("model");//根节点
				Element properties =this.createElement("properties");//属性节点的根
				model.appendChild(properties);
	
				for(int i=0; i <names.length; i++){
					Element propertie =this.createElement("property");//每一个属性节点
	
					Element name =this.createElement("name");//每一个属性节点
					Element type =this.createElement("type");//每一个属性节点
					Element nullable =this.createElement("nullable");//每一个属性节点
					Element note =this.createElement("note");//每一个属性节点
					Element check =this.createElement("check");//每一个属性节点
					Element show =this.createElement("show");//每一个属性节点
	
					Text nameTxt =this.createText(names[i]);
	
					Text typeTxt =null;
					Text nullableTxt =null;
					Text noteTxt =null;
					Text checkTxt =null;
					Text showTxt =null;
					try{
						typeTxt = this.createText( types[i] );
					}catch(ArrayIndexOutOfBoundsException e){
						typeTxt = this.createText( "" );
					}
					try{
						nullableTxt = this.createText( nullables[i] );
					}catch(ArrayIndexOutOfBoundsException e){
						nullableTxt = this.createText( "" );
					}
					try{
						noteTxt = this.createText( notes[i] );
					}catch(ArrayIndexOutOfBoundsException e){
						noteTxt = this.createText( "" );
					}
					try{
						checkTxt = this.createText( checks[i] );
					}catch(ArrayIndexOutOfBoundsException e){
						checkTxt = this.createText( "" );
					}
					try{
						showTxt = this.createText( shows[i] );
					}catch(ArrayIndexOutOfBoundsException e){
						showTxt = this.createText( "" );
					}
					propertie.appendChild(name);
					propertie.appendChild(type);
					propertie.appendChild(nullable);
					propertie.appendChild(note);
					propertie.appendChild(check);
					propertie.appendChild(show);
	
					name.appendChild(nameTxt);
					type.appendChild(typeTxt);
					nullable.appendChild(nullableTxt);
					note.appendChild(noteTxt);
					check.appendChild(checkTxt);
					show.appendChild(showTxt);
	
					properties.appendChild(propertie);
				}
	
				//把根节点添加到文档对象内	
				doc.appendChild(model);
	
				//保存文件
				TransformerFactory tff=TransformerFactory.newInstance();
				Transformer tf=tff.newTransformer();
				tf.setOutputProperty(OutputKeys.ENCODING,"GB2312"); 	// 格式
				tf.setOutputProperty(OutputKeys.INDENT,"yes"); 	// 格式
				System.out.println("create file,file name is "+prj_path+"model/"+modelName+"___"+modelNameNote+".woo.model.xml");
				
				tf.transform( new DOMSource(doc),new StreamResult(new File(prj_path+"model/"+modelName+"___"+modelNameNote+".woo.model.xml")));
			}	// 由java创建dom文档文件完成。

			// java xml类替换为下面的，由内容直接生成dom文档：
			ServletInputStream stream = request.getInputStream();
			int len = request.getContentLength(); 
			byte ba[] = new byte[len];
			stream.read(ba);
			log.debug( prj_path+"model/"+modelName+"___"+modelNameNote+".woo.model.xml" );

			File fl = null;
			fl = new File(prj_path+"model");
			if(!fl.exists()) {
				fl.mkdirs();
			}

			// 中文文件名导致UTF-8为文件编码格式？ Demo表 就会使用UTF-8编码？
			//modelNameNote = "aa中文";
			//modelNameNote = "Demoab表"; 
			fl = new File(prj_path+"model/"+modelName+"___"+modelNameNote+".woo.model.xml") ;
			
			if(fl.exists()) {
				fl.delete();
			}
			//fl.createNewFile();
			
			//System.out.println( new String(ba) );
			//System.out.println( new String(ba,"utf-8") );
			//System.out.println( new String(ba,"gbk") );
			// 页面gbk, ajax提交内容为utf-8,生成模型文件gb2312, 读取模型文件传入页面为gb2312。这些以后要统一为utf-8最好。
			FileUtils.writeStringToFile( fl
					, ("<?xml version=\"1.0\" encoding=\"GB2312\"?>"+new String(ba, "utf-8") ), null ); //.writeStringToFile
//					//采用系统默认编码，即ANSI编码。
//			FileUtils.writeByteArrayToFile(fl,
//					"<?xml version=\"1.0\" encoding=\"GB2312\"?>".getBytes() );
			
			// 生成本地的GB2312格式的文件。成功之后提示给客户端，信息采用 UTF-8格式输出。
			response.setContentType("text/xml;charset=UTF-8");
			printWriter = response.getWriter();
			printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			printWriter.println("<response>");
			printWriter.println("<content>true</content>");
			printWriter.println("<content>生成文件成功！</content>");
			printWriter.println("</response>");
			return null;

		}catch(Exception e){
			e.printStackTrace() ;
		}
		
		return null;//mapping.findForward("");
	}

	/**
	 * <p>读取请求的模型文件。</p>
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 */
	private ActionForward getModelFileInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
		
		// 1。获取参数并且验证
		String modelEn = request.getParameter("modelEn");//模型的英文名，即保存的文件名
		String modelCh = request.getParameter("modelCh");//模型的中文注释名
		try {
			//modelEn = StringUtils.toGB2312(modelEn);
			//modelCh = StringUtils.toGB2312(modelCh);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		File file=new File( prj_path+"model/"+modelEn+"___"+modelCh+".woo.model.xml");
		if(!file.exists()){
			System.out.println("模型文件"+ file.getName()+"不存在！");
			return null;

		}
		
		// 2。参数可以处理的基础上，读取模型文件内容，输出模型文件内容 -- 采用GB2312格式，文件是基于该格式的。
		log.info("get file,file name is "+prj_path+"model/"+modelEn+"___"+modelCh+".woo.model.xml");
		
		response.setContentType("text/xml; charset=GB2312");
		response.setHeader("Cache-Control","no-cache");

		PrintWriter printWriter=null;
		try {
			printWriter = response.getWriter();

			//		读取文件内容
			java.io.FileReader fr=new java.io.FileReader(file);//建立FileReader对象，并实例化为fr
			java.io.BufferedReader br=new java.io.BufferedReader(fr);//建立BufferedReader对象，并实例化为br
			String line=br.readLine();//从文件读取一行字符串
			//判断读取到的字符串是否不为空
			while(line!=null){
				printWriter.println(line );//输出从文件中读取的数据	 //.trim() + "\n"
				line=br.readLine();//从文件中继续读取一行数据
			}
			br.close();//关闭BufferedReader对象
			fr.close();//关闭文件

			printWriter.close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	

		return null;
	}

	/**
	 * 创建一个节点元素
	 * @param element
	 * @return
	 */
	private Element createElement(String element){
		Element el=doc.createElement(element);
		return el;
	}
	
	/**
	 * 创建一个文本
		Text txt=doc.createTextNode(textName);
	 * @param textName
	 * @return
	 */
	private Text createText(String textName){
		Text txt=doc.createTextNode(textName);
		return txt;
	}
	
}
